#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QDateTime>
#include <QThread>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    serialPort = new QSerialPort(this);    //在窗口加入一个串口控制对象
    timer = new QTimer(this);//定时发送
    QTimer* getSysTimeTimer = new QTimer(this);//定时器每100ms刷新时间
    buttonConTimer = new QTimer(this);    //定时器循环发送文本
    //myThread  = new CustomThread(this);   //线程

    this->setLayout(ui->gridLayoutGlobal);

    //控制参数与控件初始化
    buttonIndex = 0;
    writeCntTotal = 0;
    readCntTotal = 0;
    serialStatus = false;
    ui->btnSendContext->setEnabled(false);
    ui->checkBoxSendIntime->setEnabled(false);
    ui->checkBoxSendNewLine->setEnabled(false);
    ui->checkBoxHexSend->setEnabled(false);
    getSysTimeTimer->start(100);


    connect(serialPort,&QSerialPort::readyRead,this,&Widget::_SerialData_readyToRead);
    connect(timer,&QTimer::timeout,[=](){on_btnSendContext_clicked();});
    connect(getSysTimeTimer,SIGNAL(timeout()),this,SLOT(time_reflash()));
    //捕捉自定义控件refresh信号，更新端口号
    connect(ui->comboBox_serialNum, &MyComboBox::refresh, this, &Widget::refreshSerialName);
    connect(buttonConTimer, &QTimer::timeout, this, &Widget::buttons_handler);//定时器信号与槽绑定
    //connect(myThread, &CustomThread::threadTimeOut, this, &Widget::buttons_handler);//线程信号与槽的绑定

    ui->comboBox_boautrate->setCurrentIndex(6);
    ui->comboBox_databit->setCurrentIndex(3);
    refreshSerialName();//启动后更新加载系统中可用串口
    ui->labelSendStatus->setText(ui->comboBox_serialNum->currentText() + "NotOpen!");

    //用数组存储ui中那一列的按钮

    for(int i = 1; i <= 9; i++){
        QString btnName = QString("pushButton_%1").arg(i);
        QPushButton* btn = findChild<QPushButton*>(btnName);
        if(btn){
            btn->setProperty("buttonId",i);
            buttons.append(btn);
            connect(btn, SIGNAL(clicked()), this, SLOT(on_command_button_clicked()));
        }

        QString lineEditName = QString("lineEdit_%1").arg(i);
        QLineEdit* lineEdit = findChild<QLineEdit*>(lineEditName);
        lineEdits.append(lineEdit);

        QString checkBoxName = QString("checkBox_%1").arg(i);
        QCheckBox* checkBox = findChild<QCheckBox*>(checkBoxName);
        checkBoxs.append(checkBox);
    }

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_btnSendContext_clicked()
{
    int writeCnt = 0;
    //读取内容
    const char* sendData = ui->lineEditSendContext->text().toLocal8Bit().constData();
    //判断是否16进制发送，如果是的话
    if(ui->checkBoxHexSend->isChecked()){
        QString tmp = ui->lineEditSendContext->text();
        //判断是否是偶数位
        QByteArray tmpArray = tmp.toLocal8Bit();
        if(tmpArray.size() % 2 != 0){
            ui->labelSendStatus->setText("Error Input!");
            return;
        }
        //判断是否符合十六进制表达式
        for(auto c : tmpArray){
            if(!std::isxdigit(c)){
                ui->labelSendStatus->setText("Error Input!");
                return;
            }
        }
        if(ui->checkBoxSendNewLine->isChecked()){
            tmpArray.append("\r\n");
        }
        //转换成16进制发送， 用户输入1，变成1，拒绝变成字符1
        QByteArray arraySend = QByteArray::fromHex(tmpArray);
        writeCnt = serialPort->write(arraySend);

    }else{
        //如果不是16进制发送
        if(ui->checkBoxSendNewLine->isChecked()){   //发送新行
            QByteArray arraySendData(sendData, strlen(sendData));
            arraySendData.append("\r\n");
            writeCnt = serialPort->write(arraySendData);
        }
        else writeCnt = serialPort->write(sendData);
    }

    //发送失败清空
    if(writeCnt == -1){
        ui->labelSendStatus->setText("Send Error!");
    }else{
        //发送成功情况
        writeCntTotal += writeCnt;
        //qDebug() << "sendOk" << sendData << "cnt:" << writeCnt;

        ui->labelSendStatus->setText("Send OK!");
        ui->labelSendcnt->setText("Sent:"+QString::number(writeCntTotal));

        if(strcmp(sendData, sendBak.toStdString().c_str()) != 0){
            ui->textEditRecord->append(sendData);
            sendBak = QString::fromUtf8(sendData);
        }
    }
}

void Widget::_SerialData_readyToRead()
{
    QString revMessage = serialPort->readAll();
    //qDebug() << "revCnt:" << revMessage.size() << "context:" + revMessage;
    if(revMessage != NULL){
        if(ui->checkBoxLine->isChecked()){
            revMessage.append("\r\n");
        }
        //16进制显示
        if(ui->checkBoxHexShow->isChecked()){
            QByteArray tmpHexString = revMessage.toUtf8().toHex().toUpper();
            //原来控件上的内容用HEX显示
            QString tmpStringHex = ui->textEditRev->toPlainText();//将接收区内容取出来
            tmpHexString = tmpStringHex.toUtf8() + tmpHexString;//将旧的原来的HEX和新的内容拼接起来（注意先后顺序）
            //重新显示在控件上
            ui->textEditRev->setText(QString::fromUtf8(tmpHexString));
        }else {
            //非16进制显示
            if(ui->checkBoxRevTime->checkState() == Qt::Checked){
                getSysTime();
                ui->textEditRev->insertPlainText("【"+myTime+"】"+revMessage);
            }else if(ui->checkBoxRevTime->checkState() == Qt::Unchecked){
                ui->textEditRev->insertPlainText(revMessage);
            }
        }
        //接收总字节数
        readCntTotal += revMessage.size();
        //显示接收总字节数
        ui->labelRevCnt->setText("Received:"+QString::number(readCntTotal));

        ui->textEditRev->moveCursor(QTextCursor::End);//光标移至文本末尾
        ui->textEditRev->ensureCursorVisible();//显示文本最底下底下
        //ui->textEditRev->setFocus();
    }

}

void Widget::on_btnCloseOrOpenSerial_clicked(bool checked)
{
    if(checked){
        //1.选择端口号
        serialPort->setPortName(ui->comboBox_serialNum->currentText());
        //2.配置波特率
        serialPort->setBaudRate(ui->comboBox_boautrate->currentText().toInt());
        //3.配置数据位
        serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_databit->currentText().toUInt()));
        //4.配置校验位
        switch (ui->comboBox_jiaoyan->currentIndex()) {
        case 0: serialPort->setParity(QSerialPort::NoParity);break;
        case 1: serialPort->setParity(QSerialPort::EvenParity);break;
        case 2: serialPort->setParity(QSerialPort::MarkParity);break;
        case 3: serialPort->setParity(QSerialPort::OddParity);break;
        case 4: serialPort->setParity(QSerialPort::SpaceParity);break;
        default: serialPort->setParity(QSerialPort::UnknownParity);break;
        }
        //5.配置停止位
        serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_databit->currentText().toUInt()));
        //6.流控
        if(ui->comboBox_fileCon->currentText() == "None"){
            serialPort->setFlowControl(QSerialPort::NoFlowControl);
        }

        //7.打开串口
        if(serialPort->open(QIODevice::ReadWrite)){
            //qDebug() << "serial open sucess!";
            ui->comboBox_databit->setEnabled(false);
            ui->comboBox_fileCon->setEnabled(false);
            ui->comboBox_jiaoyan->setEnabled(false);
            ui->comboBox_stopbit->setEnabled(false);
            ui->comboBox_boautrate->setEnabled(false);
            ui->comboBox_serialNum->setEnabled(false);
            ui->btnCloseOrOpenSerial->setText("关闭串口");
            ui->btnSendContext->setEnabled(true);
            ui->checkBoxSendIntime->setEnabled(true);
            ui->checkBoxSendNewLine->setEnabled(true);
            ui->checkBoxHexSend->setEnabled(true);
            ui->labelSendStatus->setText(ui->comboBox_serialNum->currentText() + "isOpen!");
        }else{
            QMessageBox msgBox;
            msgBox.setMinimumWidth(200);
            msgBox.setMinimumHeight(200);
            msgBox.setWindowTitle("打开串口错误！");
            msgBox.setText("串口可能被占用或者已拔出！");
            msgBox.exec();
        }
    }else{
        //关闭串口后，设置各个控件的使能，恢复可配置状态
        serialPort->close();
        ui->comboBox_databit->setEnabled(true);
        ui->comboBox_fileCon->setEnabled(true);
        ui->comboBox_jiaoyan->setEnabled(true);
        ui->comboBox_stopbit->setEnabled(true);
        ui->comboBox_boautrate->setEnabled(true);
        ui->comboBox_serialNum->setEnabled(true);
        ui->btnCloseOrOpenSerial->setText("打开串口");
        ui->btnSendContext->setEnabled(false);
        ui->checkBoxSendIntime->setEnabled(false);
        ui->checkBoxSendIntime->setCheckState(Qt::Unchecked);
        timer->stop();
        ui->lineEditSendContext->setEnabled(true);
        ui->lineEditEachTime->setEnabled(true);
        ui->checkBoxSendNewLine->setEnabled(false);
        ui->checkBoxHexSend->setEnabled(false);
        ui->labelSendStatus->setText(ui->comboBox_serialNum->currentText() + "isClose!");
    }
}

void Widget::on_checkBoxSendIntime_clicked(bool checked)
{
    //定时发送个控价状态设置
    if(checked){
        ui->lineEditSendContext->setEnabled(false);
        ui->lineEditEachTime->setEnabled(false);
        timer->start(ui->lineEditEachTime->text().toInt());
    }else{
        timer->stop();
        ui->lineEditSendContext->setEnabled(true);
        ui->lineEditEachTime->setEnabled(true);
    }
}

void Widget::on_btnRevClear_clicked()
{
    ui->textEditRev->setText("");
}

void Widget::on_btnRevSave_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this,tr("Save File"), "D:/qt_project/bigProject/serialsData.txt", tr("Text (*.txt)"));
    if(fileName != NULL){
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
            return;

        QTextStream out(&file);
        out << ui->textEditRev->toPlainText();
        file.close();
    }

}

void Widget::time_reflash()
{
    getSysTime();
    ui->labelCurrentTime->setText(myTime);
}

void Widget::getSysTime()
{
    QDateTime currentTime = QDateTime::currentDateTime();
    QDate date = currentTime.date();
    QTime time = currentTime.time();
    int year = date.year();
    int month = date.month();
    int day = date.day();
    int hour = time.hour();
    int minute = time.minute();
    int second = time.second();
    myTime = QString("%1-%2-%3 %4:%5:%6").arg(year)
            .arg(month,2,10,QChar('0')).
            arg(day,2,10,QChar('0')).
            arg(hour,2,10,QChar('0')).
            arg(minute,2,10,QChar('0')).
            arg(second,2,10,QChar('0'));
}

void Widget::on_checkBoxHexShow_clicked(bool checked)
{
    if(checked){
        //1.读取textEdit上的内容
        QString tmp = ui->textEditRev->toPlainText();
        //2.转换成hex
        QByteArray qtmp = tmp.toUtf8();
        qtmp = qtmp.toHex();
        //3.显示
        QString lastShow;
        tmp = QString::fromUtf8(qtmp);
        //每两位大写字母间距一个空格的显示
        for(int i = 0; i < tmp.size(); i += 2){
            lastShow += tmp.mid(i, 2) + " ";
        }
        ui->textEditRev->setText(lastShow.toUpper());
    }else{
        QString tmpHexString = ui->textEditRev->toPlainText();
        QByteArray tepHexQByteArray = tmpHexString.toUtf8();
        QByteArray tmpByteString = QByteArray::fromHex(tepHexQByteArray);
        ui->textEditRev->setText(QString::fromUtf8(tmpByteString));
    }
    ui->textEditRev->moveCursor(QTextCursor::End);//光标移至文本末尾
    ui->textEditRev->ensureCursorVisible();//显示文本最底下底下
}

void Widget::on_btnHideTable_clicked(bool checked)
{
    if(checked){
        ui->btnHideTable->setText("拓展面板");
        ui->groupBoxTexts->hide();
    }else{
        ui->btnHideTable->setText("隐藏面板");
        ui->groupBoxTexts->show();
    }
}

void Widget::on_btnHideHistory_clicked(bool checked)
{
    if(checked){
        ui->btnHideHistory->setText("拓展历史");
        ui->groupBoxRecord->hide();
    }else{
        ui->btnHideHistory->setText("隐藏历史");
        ui->groupBoxRecord->show();
    }
}

void Widget::refreshSerialName()
{
    ui->comboBox_serialNum->clear();
    //检测系统可用串口，并更新到comboBox上待用户选择
    QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();
    for(QSerialPortInfo serialInfo : serialList){
        //qDebug() << serialInfo.portName();
        ui->comboBox_serialNum->addItem(serialInfo.portName());
    }
    ui->labelSendStatus->setText("Com Refresh!");
}

void Widget::on_command_button_clicked()
{
    QPushButton* btn = qobject_cast<QPushButton*>(sender());
    if(btn){
        int num = btn->property("buttonId").toInt();
        QString lineEditName = QString("lineEdit_%1").arg(num);
        QLineEdit* lineEdit = findChild<QLineEdit*>(lineEditName);
        if(lineEdit){
            if(lineEdit->text().size() <= 0){
                return;
            }
            ui->lineEditSendContext->setText(lineEdit->text());
        }

        QString checkBoxName = QString("checkBox_%1").arg(num);
        QCheckBox* checkBox = findChild<QCheckBox*>(checkBoxName);
        if(checkBox){
            ui->checkBoxHexSend->setChecked(checkBox->isChecked());
        }
        on_btnSendContext_clicked();
    }

}

void Widget::buttons_handler(){
    if(buttonIndex < buttons.size()){
        QPushButton* btnTmp = buttons[buttonIndex];
        emit btnTmp->clicked();
        buttonIndex++;
    }else buttonIndex = 0;


//    for(int i = 0;i < buttons.size(); i++){
//        QPushButton* btnTmp = buttons[i];
//        emit btnTmp->clicked();
//        QThread::msleep(ui->spinBox->text().toUInt());//不能在ui线程当中延时，否则导致页面刷新问题！
//    }
}

void Widget::on_checkBox_send_clicked(bool checked)
{
    if(checked){
        ui->spinBox->setEnabled(false);
        //myThread->start();
        buttonConTimer->start(ui->spinBox->text().toUInt());
    }else{
        ui->spinBox->setEnabled(true);
        buttonConTimer->stop();
        //myThread->stop();
    }
}

void Widget::on_pushButtonInit_clicked()
{
    QMessageBox msgBox;
    msgBox.setWindowTitle("提示");
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setText("重置列表不可逆确认是否重置？");
    //msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    QPushButton* yesButton = msgBox.addButton("是",QMessageBox::YesRole);
    QPushButton* noButton = msgBox.addButton("是",QMessageBox::NoRole);
    msgBox.exec();
    if(msgBox.clickedButton() == yesButton){
        //qDebug() << "YesButton";
        for(int i = 0; i < lineEdits.size(); i++){
            //遍历lineEdit，并清空内容
            lineEdits[i]->clear();
            //遍历checkBox，并取消勾选
            checkBoxs[i]->setCheckable(false);
        }

    }
    if(msgBox.clickedButton() == noButton){
        //qDebug() << "NoButton";
    }
}

void Widget::on_pushButtonSave_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存文件"),
                                "D:/qt_project/bigProject/load.txt",
                                tr("文本类型 (*.txt)"));
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;

    QTextStream out(&file);
    for(int i = 0; i < lineEdits.size(); i++){
        out << checkBoxs[i]->isChecked() << "|" << lineEdits[i]->text() << "\n";
    }
    file.close();
}

void Widget::on_pushButtonLoad_clicked()
{
    int i = 0;
    QString fileName = QFileDialog::getOpenFileName(this, tr("打开文件"),
                                "D:/qt_project/bigProject/",
                                tr("文本类型 (*.txt)"));
    if(fileName != NULL){
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;

        QTextStream in(&file);
        while(!in.atEnd() && i <= 9){
            QString line = in.readLine();
            QStringList parts = line.split("|");
            if(parts.count() == 2){
                checkBoxs[i]->setChecked(parts[0].toInt());
                lineEdits[i]->setText(parts[1]);
            }
            i++;
        }
    }
}
